/**
 * Copyright: Copyright (c) 2018
 * Company:
 *
 * @author XueWei
 * @date 2018年9月4日 上午10:57:17
 * @version V1.0
 */
package com.smartcommunity.service.dataImport;

import cn.hutool.core.util.StrUtil;
import com.smartcommunity.base.bean.ExceptionCode;
import com.smartcommunity.base.common.DataImport;
import com.smartcommunity.bean.constant.Constant;
import com.smartcommunity.bean.entity.ImportErrorMsg;
import com.smartcommunity.bean.entity.ImportField;
import com.smartcommunity.controller.DataImportBase;
import com.smartcommunity.dao.village.RealCompanyDao;
import com.smartcommunity.entity.village.RealCompany;
import com.smartcommunity.exception.BusinessException;
import com.smartcommunity.log.interceptor.Log;
import com.smartcommunity.service.dataImport.model.RealCompanyExportModel;
import com.smartcommunity.utils.RegExUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.apache.commons.lang3.StringUtils.length;

/**
 * @ClassName: RealCompanyImport
 * @Description: 实有单位导入
 * @author XueWei
 * @date 2018年9月4日 上午10:57:17
 *
 */
@Component("realCompany")
@Slf4j
public class RealCompanyImport extends DataImportBase implements DataImport {

    @Autowired
    private RealCompanyDao realCompanyDao;

    /**
     * 模板类型
     */
    private String type = "实有单位";

    /**
     * 内容标题
     */
    private  String[] headerTitle = new String[]{"单位名称","地址","经度","纬度"};

    /**
     * 错误信息
     */
    private  String[] headerErrorMsg = new String[]{"为空、或长度超多32位","长度超过64位","格式错误","格式错误"};

    /**
     * key taskId,value progress
     */
    final int cacheSize = 100000;
    Map<String, Integer> progressTag = new LinkedHashMap<String, Integer>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
            return size() > cacheSize;
        }
    };

    @Override
    @Log(info = "实有单位模板导入")
    public String importData(List list, String villageCode,String fileName,String taskId, HttpServletResponse response) {
        progressTag.put(taskId, 10);
        //小区编号（必填）
        if (StringUtils.isBlank(villageCode)) {
            throw new IllegalArgumentException("小区编号为空！");
        }

        //初始化导入模板信息
        ImportErrorMsg msg = getFiledInfo(type,headerTitle,headerErrorMsg);

        //字段校验信息
        List<ImportField> fieldList = msg.getFieldList();

        //获取小区下所有实有单位
        Map<String, Object> paramMap = new HashMap<>(2);
        paramMap.put("villageCode", villageCode);
        List<RealCompany> companyList = realCompanyDao.listRealCompanies(paramMap);
        List<String> companyNames = companyList.stream().map(item ->item.getCompanyName()).collect(Collectors.toList());

        List<RealCompany> addCompany = new ArrayList<>();
        List<RealCompany> updateCompany= new ArrayList<>();
        List<Object[]> objList = (List<Object[]>) list;
        //存储错误信息
        List<RealCompanyExportModel> dataListCopy = new ArrayList<>();

        RealCompany realCompany;
        int size = objList.size();
        int errorCount = 0;
        for (int i = 0; i < size; i++) {
            float percent = (float) (i + 1) / (float) size;
            progressTag.put(taskId, Math.round(percent * 100));
            boolean isError = false;

            int currentRow = Constant.START_ROW + i ;
            Object[] objects = objList.get(i);

            int fixColumnLen = 4;
            if(objects.length < fixColumnLen){
                throw new BusinessException("模板文件列数不对，请检查模板文件！");
            }

            // 空行校验，跳过空行
            List<String> oneLine = Arrays.stream(objects)
                    .map(o -> StrUtil.trim(Objects.toString(o, EMPTY)))
                    .collect(Collectors.toList());
            if(oneLine.stream().allMatch(StrUtil::isEmpty)){
                log.info("第{}行全为空，跳过该行",currentRow);
                continue;
            }

            realCompany = new RealCompany();
            realCompany.setCompanyId(UUID.randomUUID().toString().replace("-", ""));
            realCompany.setVillageCode(villageCode);
            StringBuffer errorMessages = new StringBuffer();
            // 单位名称（必填）
            String companyName = "null".equals(String.valueOf(objects[0])) ? "" : String.valueOf(objects[0]);
            if (StringUtils.isBlank(companyName) || length(companyName)>32) {
                //添加错误的行数
//                SetErrorRow(headerTitle[0],currentRow,fieldList);
                String errorMsg = appendErrorMsg(fieldList.get(0).getTitle(), companyName, fieldList.get(0).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else {
                realCompany.setCompanyName(companyName);
            }

            // 地址（非必填）
            String companyAddress = "null".equals(String.valueOf(objects[1])) ? "" : String.valueOf(objects[1]);
            if (!"".equals(companyAddress) ) {
                if(length(companyAddress)>64){
//                    SetErrorRow(headerTitle[1],currentRow,fieldList);
                    String errorMsg = appendErrorMsg(fieldList.get(1).getTitle(), companyAddress, fieldList.get(1).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                realCompany.setCompanyAddress(companyAddress);
            }
//            //联系电话(单位)(非必填)
//            String companyTel = "null".equals(String.valueOf(objects[2])) ? "" : String.valueOf(objects[2]);
//            if (!"".equals(companyTel)) {
//                if(!RegExUtils.isPhone(companyTel) &&!RegExUtils.isPhoneStaion(companyTel)){
//                    //添加错误的行数
//                    SetErrorRow(headerTitle[2],currentRow,fieldList);
//                    isError = true;
//                }
//                realCompany.setCompanyTel(companyTel);
//            }
//            //法定代表人姓名
//            String leaderName = "null".equals(String.valueOf(objects[3])) ? "" : String.valueOf(objects[3]);
//            if (!"".equals(leaderName)) {
//                realCompany.setLeaderName(leaderName);
//            }
//            //公民身份证号
//            String credentialNo = "null".equals(String.valueOf(objects[4])) ? "" : String.valueOf(objects[4]);
//            if (!"".equals(credentialNo)) {
//                realCompany.setCredentialNo(credentialNo);
//            }
//            //联系电话(法人)
//            String leaderTel = "null".equals(String.valueOf(objects[5])) ? "" : String.valueOf(objects[5]);
//            if (!"".equals(leaderTel)) {
//                if(!RegExUtils.isPhone(leaderTel) &&!RegExUtils.isPhoneStaion(leaderTel)){
//                    //添加错误的行数
//                    SetErrorRow(headerTitle[5],currentRow,fieldList);
//                    isError = true;
//                }
//                realCompany.setLeaderTel(leaderTel);
//            }
            //经度(非必填)
            String lon = "null".equals(String.valueOf(objects[2])) ? "" : String.valueOf(objects[2]);
            if (lon != null && !"null".equals(lon) && !"".equals(lon)) {
                if(!RegExUtils.isLongitude(lon)){
                    //添加错误的行数
//                    SetErrorRow(headerTitle[2],currentRow,fieldList);
                    String errorMsg = appendErrorMsg(fieldList.get(2).getTitle(), lon, fieldList.get(2).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }else{
                    realCompany.setLon(Double.valueOf(StringUtils.trimToEmpty(lon)));
                }

            }
            //纬度(非必填)
            String lat = "null".equals(String.valueOf(objects[3])) ? "" : String.valueOf(objects[3]);
            if (lat != null && !"null".equals(lat) && !"".equals(lat)) {
                if(!RegExUtils.isLatitude(lat)){
                    //添加错误的行数
//                    SetErrorRow(headerTitle[3],currentRow,fieldList);
                    String errorMsg = appendErrorMsg(fieldList.get(3).getTitle(), lat, fieldList.get(3).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }else{
                    realCompany.setLat(Double.valueOf(StringUtils.trimToEmpty(lat)));
                }
            }

            //判断当前行是否有错误
            if(isError){
                errorCount++;
                RealCompanyExportModel exportModel = new RealCompanyExportModel();
                exportModel.setCompanyName(companyName);
                exportModel.setCompanyAddress(companyAddress);
                exportModel.setLon(lon);
                exportModel.setLat(lat);
                exportModel.setErrorMsg(errorMessages.toString());
                dataListCopy.add(exportModel);
            }else{
                //判断是更新还是新增
                if(companyNames.contains(realCompany.getCompanyName())){
                    updateCompany.add(realCompany);
                }else{
                    addCompany.add(realCompany);
                }
            }
        }

        try {
            progressTag.put(taskId, 20);
            if(!updateCompany.isEmpty()){
                realCompanyDao.batchUpdateRealCompanyByName(updateCompany);
            }
            progressTag.put(taskId, 60);
            if(!addCompany.isEmpty()){
                realCompanyDao.addRealCompanyByList(addCompany);
            }
            //正常的数据需要导入进去，错误的数据返回到Excel
            if (errorCount>0) {
                String errorFileName = exportExcelToLocal(taskId,fileName,headerTitle,dataListCopy);
                progressTag.put(taskId,100);
                return errorFileName;
            }
        } catch (Exception e) {
            log.error("实有单位导入失败,保存数据库异常！",e);
            throw new BusinessException(ExceptionCode.COMPANY_SQL_EXCEPTION_CODE,"实有单位导入失败,保存数据库异常！"+e.getMessage());
        }
        log.info("实有单位导入完成");
        progressTag.put(taskId, 100);
        return "";
    }

    @Override
    public int getImportDataProgress(String taskId) {
        return progressTag.get(taskId) == null ? 0 : progressTag.get(taskId);
    }
}
